
#include "common.h"
#include <cassert>
#include <string>
#include <vector>

#include "openssl/md5.h"
#include "openssl/sha.h"
#include "openssl/des.h"
#include "openssl/rsa.h"
#include "openssl/pem.h"
#include <b64/decode.h>
#include <b64/encode.h>

// 公钥加密
std::string rsa_pub_encrypt(const std::string &clearText, const std::string &pubKey)
{
    std::string strRet;
    RSA *rsa = NULL;
    BIO *keybio = BIO_new_mem_buf((unsigned char *)pubKey.c_str(), -1);
    // 此处有三种方法
    // 1, 读取内存里生成的密钥对，再从内存生成rsa
    // 2, 读取磁盘里生成的密钥对文本文件，在从内存生成rsa
    // 3，直接从读取文件指针生成rsa
    RSA *pRSAPublicKey = RSA_new();
    rsa = PEM_read_bio_RSAPublicKey(keybio, &rsa, NULL, NULL);

    int len = RSA_size(rsa);
    char *encryptedText = (char *)malloc(len + 1);
    memset(encryptedText, 0, len + 1);

    // 加密函数
    int ret = RSA_public_encrypt(clearText.length(), (const unsigned char *)clearText.c_str(), (unsigned char *)encryptedText, rsa, RSA_PKCS1_PADDING);
    if (ret >= 0)
        strRet = std::string(encryptedText, ret);

    // 释放内存
    free(encryptedText);
    BIO_free_all(keybio);
    RSA_free(rsa);

    return strRet;
}

// 私钥解密
std::string rsa_pri_decrypt(const std::string &cipherText, const std::string &priKey)
{
    std::string strRet;
    RSA *rsa = RSA_new();
    BIO *keybio;
    keybio = BIO_new_mem_buf((unsigned char *)priKey.c_str(), -1);

    // 此处有三种方法
    // 1, 读取内存里生成的密钥对，再从内存生成rsa
    // 2, 读取磁盘里生成的密钥对文本文件，在从内存生成rsa
    // 3，直接从读取文件指针生成rsa
    rsa = PEM_read_bio_RSAPrivateKey(keybio, &rsa, NULL, NULL);

    int len = RSA_size(rsa);
    char *decryptedText = (char *)malloc(len + 1);
    memset(decryptedText, 0, len + 1);

    // 解密函数
    int ret = RSA_private_decrypt(cipherText.length(), (const unsigned char *)cipherText.c_str(), (unsigned char *)decryptedText, rsa, RSA_PKCS1_PADDING);
    if (ret >= 0)
        strRet = std::string(decryptedText, ret);

    // 释放内存
    free(decryptedText);
    BIO_free_all(keybio);
    RSA_free(rsa);

    return strRet;
}

int main()
{
    // 1.获取 密钥,公钥
    string rsa_public_key_path = "public_key.pem";
    string rsa_private_key_path = "private_key.pem";
    string public_key = read_file_to_string(rsa_public_key_path);
    string private_key = read_file_to_string(rsa_private_key_path);
    cout << "public_key" << endl;
    cout << public_key << endl;
    cout << "private_key" << endl;
    cout << private_key << endl;

    // 2.1 rsa加密
    string buf = "hello world";
    string encode_buf;
    encode_buf = rsa_pub_encrypt(buf, public_key);
    int len = encode_buf.length();

    // 2.2 base64编码
    char encode_buf_base64[512] = {0};
    int encode_buf_base64_len;
    base64::encoder E;
    encode_buf_base64_len = E.encode(encode_buf.c_str(), encode_buf.length(), encode_buf_base64);
    cout << "encode_buf_base64" << endl;
    cout << encode_buf_base64 << endl;

    // 3.1 base64解码
    char decode_buf_base64[512] = {0};
    base64::decoder D;
    int decode_buf_base64_len;
    decode_buf_base64_len = D.decode(encode_buf_base64, encode_buf_base64_len, decode_buf_base64);

    // 3.2 rsa解密
    string decode_buf;
    // decode_buf = rsa_pri_decrypt(encode_buf, private_key);
    string new_encode_buf(decode_buf_base64);
    int new_encode_buf_len = new_encode_buf.length();
    decode_buf = rsa_pri_decrypt(new_encode_buf, private_key);
    cout << "decode_buf" << endl;
    cout << decode_buf << endl;

    return 0;
}